from django.db import models
from load_planer.models import ShippingContainer, Task
from django.contrib.auth.models import Permission,PermissionsMixin
from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager
# Create your models here.
class Tenant(models.Model):
    schema_name=models.CharField(
        max_length=75,
        unique=True,
        help_text="租户的Schema名"
    )
    organization=models.TextField(
        null=True,
        default=None,
        help_text="租户的企业名称"
    )
    created=models.DateTimeField(auto_now_add=True,help_text="数据创建时间")

from  .utils.db import get_model_permissions
from django.contrib.auth.models import Permission

class RoleManager(models.Manager):
    def get_or_create(self,name,tenant,permissions=None):
        instance,created = super().get_or_create(
            name=name,tenant=tenant
        )
        if not created:
            return instance,created
        if permissions:
            instance.permissions.set(permissions)
        return  instance,created

    def create_admin_role(self,tenant):
        #获取该角色的所有权限
        permissions = Permission.objects.all()

        #获取/创建admin角色
        instance,created = self.get_or_create(
            name='admin',
            tenant=tenant,
            permissions=permissions
        )
        return instance
      
    def create_basic_role(self,tenant):
        '''
        普通用户拥有的权限:
        -查看 用户/集装箱运柜
        -更新 用户
        -查看/创建/更新/删除 任务
        '''
        permissions = get_model_permissions(
            models=[User,ShippingContainer],
            permission_type='read'
        ) + get_model_permissions(
            models=[User],
            permission_type='change'
        ) + get_model_permissions(
            models=[Task],
            permission_type='all'
        )

    #获取任务相关的权限
        instance,created = self.get_or_create(
            name='basic',
            tenant=tenant,
            permissions=permissions
        )
        return instance


class Role(models.Model):
    objects = RoleManager()
    name=models.CharField(
        max_length=150,
        help_text='角色名称',
    )
    tenant=models.ForeignKey(
        Tenant,
        related_name='roles',
        help_text='该角色所属租户',
        on_delete=models.SET_NULL,
        null=True
    )
    permissions=models.ManyToManyField(
        Permission,
        help_text='该角色所拥有的权限',
        blank=True
    )
    created=models.DateTimeField(auto_now_add=True,help_text="数据创建时间")
    
class UserManager(BaseUserManager):
    def create(self,roles=None,**user_attrs):
        username=User.get_default_username(user_attrs['email'])
        instance=self.model(username=username,**user_attrs)
        instance.set_password(user_attrs['password'])
        instance.save()
        if roles:
            instance.roles.set(roles)
        return instance
class User(AbstractBaseUser,PermissionsMixin):
    objects=UserManager()
    USERNAME_FIELD='username'
    email=models.EmailField()
    username=models.TextField(
        unique=True
    )
    first_name=models.CharField(default='',help_text='姓',max_length=100)
    last_name=models.CharField(default='',help_text='名',max_length=100)
    tenant=models.ForeignKey(
        Tenant,
        related_name='users',
        help_text='该用户的所属租户',
        on_delete=models.CASCADE,
        null=True
    )
    roles=models.ManyToManyField(
        Role,
        blank=True,
        help_text='该用户的角色',
        related_name='user_set',
        related_query_name='user'
    )
    created=models.DateTimeField(auto_now_add=True,help_text="数据创建时间")
    @staticmethod
    def get_default_schema(email:str):
        import hashlib
        if not email:
            return None
        email =email.lower().strip()
        HASH_LEN=8
        email_hash=hashlib.blake2b(
            bytes(email,'ascii'),
            digest_size=HASH_LEN
        ).hexdigest()
        return 'zmm_' + email_hash
    
    def get_default_username(email:str):
        if not email:
            return None
        schmea_name=User.get_default_schema(email)
        return f'{email}_{schmea_name}'